home *** CD-ROM | disk | FTP | other *** search
- /* dview.c -- double-buffering through views
- * Copyright (c) 1988, I and I Computing, and Commodore-Amiga, Inc.
- *
- *
- * Executables based on this information may be used in software
- * for Commodore Amiga computers. All other rights reserved.
- *
- * This information is provided "as is"; no warranties are made.
- * All use is at your own risk, and no liability or responsibility is assumed.
- */
-
- #include "sysall.h"
- #include "dview.h"
-
- /* 1 <-> 0 */
- #define OTHER_ONE( vid ) ( 1 - (vid) )
- #define FORBOTH( i ) for ( i = 0; i < 2; ++i)
-
- /* shorthand */
- #define ALLOC( S, flags) (AllocMem( (LONG) sizeof (struct S), (LONG) (flags)))
- #define FREE( ptr, S) FreeMem( (ptr), (LONG) sizeof (struct S));
-
- #define NUMCOLORS (32)
-
- /* allocates and sets up a DoubleView structure based on
- * an existing screen. Allocates two copies of everything
- * except the screen's bitmap and bitplanes.
- * creates copper lists.
- * returns non-zero if successful
- * assumes graphics.library is open
- */
- initDV( dv, screen )
- struct DoubleView *dv;
- struct Screen *screen;
- {
- struct View *vlord;
- struct View *v;
- struct ViewPort *vp;
- int vx; /* double view index */
- struct BitMap *sbitmap; /* screen's bitmap */
- struct BitMap *bmap;
-
- int depth;
- int i;
-
- UWORD colortable[ NUMCOLORS ]; /* screen's colors */
- int colorcount;
-
- vlord = ViewAddress();
-
- sbitmap = &screen->BitMap;
- dv->dv_Width = sbitmap->BytesPerRow << 3;
- dv->dv_Height = sbitmap->Rows;
- depth = sbitmap->Depth;
-
- /* get the screen's colors */
- colorcount = screen->ViewPort.ColorMap->Count;
- if (colorcount > NUMCOLORS) colorcount = NUMCOLORS;
- i = colorcount;
- while ( i-- )
- {
- colortable[ i ] = GetRGB4( screen->ViewPort.ColorMap, (LONG) i);
- }
-
- /*
- * initialize stuff to make it easy to clean up
- */
- dv->dv_Current = 0;
- dv->dv_RastPorts[ 0 ] = dv->dv_RastPorts[ 1 ] = NULL;
- dv->dv_Views[ 0 ] = dv->dv_Views[ 1 ] = NULL;
- dv->dv_Signal = -1;
-
- FORBOTH( vx )
- {
- /*
- * init rastports
- */
- if (!( dv->dv_RastPorts[ vx ] = ALLOC( RastPort, 0))) goto FAIL;
- InitRastPort( dv->dv_RastPorts[ vx ] );
-
- /*
- * init companion bitmap and planes
- */
- if ( vx == 1)
- {
- /* clone screen's bitmap */
- if ( !( bmap = ALLOC( BitMap, 0))) goto FAIL;
-
- InitBitMap( dv->dv_RastPorts[ vx ]->BitMap = bmap,
- (LONG) depth, (LONG) dv->dv_Width, (LONG) dv->dv_Height);
-
- for ( i = 0; i < depth; ++i )
- {
- if (!(bmap->Planes[i] =
- AllocRaster((LONG) dv->dv_Width, (LONG) dv->dv_Height)))
- {
- goto FAIL;
- }
- }
- }
- else
- {
- /* use screen's bitmap */
- bmap = dv->dv_RastPorts[ vx ]->BitMap = sbitmap;
- }
-
- /*
- * init views and viewports
- */
- if (!(v = ALLOC( View, 0 ))) goto FAIL;
- InitView( dv->dv_Views[ vx ] = v );
-
- v->DxOffset = vlord->DxOffset;
- v->DyOffset = vlord->DyOffset;
-
- if (!(v->ViewPort = ALLOC( ViewPort, 0 ))) goto FAIL;
- vp = v->ViewPort;
- InitVPort( vp );
-
- /*
- * init rasinfo, colormap
- */
- if (!(vp->RasInfo = ALLOC( RasInfo, MEMF_CLEAR))) goto FAIL;
- vp->RasInfo->BitMap = bmap;
-
- /* overkill number of colors */
- if (!(vp->ColorMap = GetColorMap( (LONG) NUMCOLORS )))
- {
- goto FAIL;
- }
-
- /* clone colors */
- LoadRGB4( vp, colortable, (LONG) colorcount);
-
- /* other viewport init */
- vp->DWidth = dv->dv_Width;
- vp->DHeight = dv->dv_Height;
- vp->Modes = screen->ViewPort.Modes & ~VP_HIDE;
-
- /*
- * set up user copper list to generate an interrupt
- * on my viewport's last line
- */
- if (!(vp->UCopIns = createUCop( vp->DHeight - 1, vp->DWidth - 1 )))
- {
- goto FAIL;
- }
-
- /*
- * create view
- */
- MakeVPort( v, vp );
- MrgCop( v );
-
- } /* end FORBOTH */
-
- /*
- * copy bitmap contents
- */
- syncDV( dv, 0);
-
- /* install video interrupt handlers */
- if ( (dv->dv_Signal = AllocSignal( (long) -1 )) == -1) goto FAIL;
-
- dv->dv_SigMask = (long) 1 << dv->dv_Signal;
- printf("SigMask: %lx\n", dv->dv_SigMask );
- installHandlers( dv->dv_Signal );
-
- return 1;
-
- FAIL:
- freeDV( dv );
- return 0;
- }
-
- /* frees everything set up by initDV(). Note that it
- * frees just one set of bitmap and planes.
- * can be used to free partial set
- * WARNING: Be Sure that neither view is current in graphics
- * mind. Call RethinkDisplay() (needn't do CloseScreen())
- * to reinstall Intuition's View
- */
- freeDV( dv )
- struct DoubleView *dv;
- {
- int vx; /* double view index */
- struct View *v;
- struct ViewPort *vp;
- struct BitMap *bmap;
- struct RastPort *rp;
- int plane;
-
- /* 0 and -1 are both "error" indicators: no clean up */
- if (dv->dv_Signal != 0 && dv->dv_Signal != -1)
- {
- removeHandlers();
- FreeSignal( (long) dv->dv_Signal );
- }
-
- WaitTOF(); /* be sure coppers and handlers aren't in use */
-
- FORBOTH( vx )
- {
- /* View hierarchy */
- if ( v = dv->dv_Views[ vx ] )
- {
- if ( vp = v->ViewPort )
- {
- if ( vp->ColorMap )
- {
- FreeColorMap( vp->ColorMap );
- }
-
- if ( vp->RasInfo ) FREE( vp->RasInfo, RasInfo );
-
- /* free the intermediate copper lists created by MakeVPort */
- FreeVPortCopLists( vp );
-
- FREE( vp, ViewPort );
- }
- /* free user copper list */
- freeUCop( vp->UCopIns );
-
- /* Free the copper lists created by MrgCop */
- FreeCprList( v->LOFCprList );
- FreeCprList( v->SHFCprList );
-
- FREE( v, View );
- dv->dv_Views[ vx ] = NULL; /* and void */
- }
-
- /* RastPort hierarchy */
- if ( rp = dv->dv_RastPorts[ vx ] )
- {
- if (vx == 1) /* only the stuff I allocated */
- {
- if ( bmap = rp->BitMap )
- {
- plane = bmap->Depth;
- while ( plane-- )
- {
- if ( bmap->Planes[ plane ] )
- {
- FreeRaster( bmap->Planes[plane],(LONG)dv->dv_Width,
- (LONG) dv->dv_Height);
- }
- }
-
- FREE( bmap, BitMap );
- }
- }
-
- FREE( rp, RastPort );
- dv->dv_RastPorts[ vx ] = NULL; /* and void */
- }
- }
- }
-
- /* copies buffers from one view buffer 'srcvid' to other */
- syncDV( dv, srcvid )
- struct DoubleView *dv;
- int srcvid;
- {
- BltBitMap( dv->dv_RastPorts[ srcvid ]->BitMap, 0L, 0L,
- dv->dv_RastPorts[ OTHER_ONE( srcvid ) ]->BitMap, 0L, 0L,
- (LONG) dv->dv_Width, (LONG) dv->dv_Height, (LONG) 0xc0, (LONG) 0xff, 0L);
- }
-
- /* install view indexed by 'vid' ,
- * initiates BOVP mechanism, returns pointer
- * to offscreen rastport
- */
- struct RastPort *
- selectDV( dv, vid )
- struct DoubleView *dv;
- int vid;
- {
- dv->dv_Current = vid;
-
- LoadView( dv->dv_Views[ vid ] );
- SetSignal( 0L, dv->dv_SigMask ); /* clear signal bit */
- return ( dv->dv_RastPorts[ OTHER_ONE( dv->dv_Current ) ] );
- }
-
- /* switches displayed view,
- * initiates BOVP mechanism, returns pointer
- * to offscreen rastport
- */
- struct RastPort *
- swapDV( dv )
- struct DoubleView *dv;
- {
- return ( selectDV( dv, OTHER_ONE( dv->dv_Current ) ) );
- }
-
- /* waits until it safe to render into offscreen buffer */
- waitDV( dv )
- struct DoubleView *dv;
- {
- Wait( dv->dv_SigMask );
- return;
- }
-
- /* returns pointer to rastport for current view */
- struct RastPort *
- onscreenDV( dv )
- struct DoubleView *dv;
- {
- return ( dv->dv_RastPorts[ dv->dv_Current ] );
- }
-
- /* returns pointer to rastport for view currently offscreen */
- struct RastPort *
- offscreenDV( dv )
- struct DoubleView *dv;
- {
- return ( dv->dv_RastPorts[ OTHER_ONE( dv->dv_Current ) ] );
- }
-
- dumpDV( dv )
- struct DoubleView *dv;
- {
- printf("DoubleView at %lx\n", dv);
- printf("current: %d, width/height %d/%d\n",
- dv->dv_Current, dv->dv_Width, dv->dv_Height);
-
- printf("rastports: %lx/%lx\n", dv->dv_RastPorts[0], dv->dv_RastPorts[1]);
-
- printf("views: %lx/%lx\n", dv->dv_Views[0], dv->dv_Views[1]);
- printf("viewports: %lx/%lx\n",
- dv->dv_Views[0]->ViewPort, dv->dv_Views[1]->ViewPort);
- printf("rasinfos %lx/%lx\n",
- dv->dv_Views[0]->ViewPort->RasInfo, dv->dv_Views[1]->ViewPort->RasInfo);
- printf("bitmaps: %lx/%lx\n",
- dv->dv_Views[0]->ViewPort->RasInfo->BitMap,
- dv->dv_Views[1]->ViewPort->RasInfo->BitMap);
-
- printf("rastports: %lx/%lx\n",
- dv->dv_RastPorts[0], dv->dv_RastPorts[1]);
-
- printf("rpbitmaps: %lx/%lx\n",
- dv->dv_RastPorts[0]->BitMap, dv->dv_RastPorts[1]->BitMap);
-
- }
-
-